﻿#pragma once

#include <stdbool.h>
#include <stdint.h>

#if WIN32
#include <windows.h>
#endif

/**
 * @brief 电压量程枚举配置
 *
 * ADC和DAC统一使用该电压量程枚举
 */
typedef enum DAQVoltage
{
    Voltage2V5 = 5, ///< 2.5V电压量程
    Voltage5V = 6,  ///< 5V电压量程
    Voltage10V = 7, ///< 10V电压量程
    Voltage15V = 8, ///< 15V电压量程
} DAQVoltage_t;

/**
 * @brief ADC采样率配置
 */
typedef enum DAQADCSampleRate
{
    SampleRate80 = 80,       ///< 80采样率
    SampleRate100 = 100,     ///< 100采样率
    SampleRate500 = 500,     ///< 500采样率
    SampleRate1K = 1000,     ///< 1K采样率
    SampleRate5K = 5000,     ///< 5K采样率
    SampleRate10K = 10000,   ///< 10K采样率
    SampleRate50K = 50000,   ///< 50K采样率
    SampleRate100K = 100000, ///< 100K采样率
} DAQADCSampleRate_t;

/**
 * @brief ADC通道配置
 * @attention 多选通道，可以使用与操作实现
 */
typedef enum DAQADCChannel
{
    AIN1 = 0b00000001,      /// ADC通道1
    AIN2 = 0b00000001 << 1, /// ADC通道2
    AIN3 = 0b00000001 << 2, /// ADC通道3
    AIN4 = 0b00000001 << 3, /// ADC通道4
    AIN5 = 0b00000001 << 4, /// ADC通道5
    AIN6 = 0b00000001 << 5, /// ADC通道6
    AIN7 = 0b00000001 << 6, /// ADC通道7
    AIN8 = 0b00000001 << 7, /// ADC通道8
} DAQADCChannel_t;

/**
 * @brief DAC通道配置
 */
typedef enum DAQDACChannel
{
    DAC1 = 0x01, /// DAC通道1
    DAC2 = 0x02, /// DAC通道2
} DAQDACChannel_t;

/**
 * @brief DAC模式配置
 */
typedef enum DAQDACMode
{
    DirectCurrent = 0x00, /// 直流
    Wave = 0x01,          /// 波形
} DAQDACMode_t;

typedef struct daq331m daq331m_t, *daq331m_ptr;

typedef struct daq331m_dll
{
#if WIN32
    HINSTANCE handle;
#elif __linux__
    void *handle;
#endif
    uint32_t *(*DAQ331M_New)(void);
    void (*DAQ331M_Delete)(uint32_t *base_class);
    uint32_t (*DAQ331M_InitializeDevice)(uint32_t *base_class);
    uint32_t (*DAQ331M_ConnectedDevice)(uint32_t *base_class);
    uint32_t (*DAQ331M_SwitchingCommunicationProtocols)(uint32_t *base_class);
    uint32_t (*DAQ331M_UseSerialBackend)(uint32_t *base_class, const char *uart_name, uint32_t baud_rate);
    uint32_t (*DAQ331M_UseTCPClientBackend)(uint32_t *base_class, const char *ip_address, int port);
    uint32_t (*DAQ331M_UseModbusRTUBackend)(uint32_t *base_class, const char *uart_name, int baud_rate, int address);
    uint32_t (*DAQ331M_ConfigureADCParameters)(uint32_t *base_class, uint32_t sample_rate, uint32_t voltage);
    uint32_t (*DAQ331M_StartCollection)(uint32_t *base_class);
    uint32_t (*DAQ331M_StopCollection)(uint32_t *base_class);
    uint32_t (*DAQ331M_TryReadADCData)(uint32_t *base_class, uint8_t channel, double *read_buffer, uint32_t read_size,
                                       uint32_t timeout);
    uint32_t (*DAQ331M_ADCDataIsReady)(uint32_t *base_class, uint32_t data_num);
    uint32_t (*DAQ331M_ConfigADCChannel)(uint32_t *base_class, uint8_t channel_state);
    uint32_t (*DAQ331M_GetADCLegalChannelSize)(uint32_t *base_class);
    uint32_t (*DAQ331M_GetADCBufferDataSize)(uint32_t *base_class, int channel);
    uint32_t (*DAQ331M_GetADCEnableChannelSize)(uint32_t *base_class);
    uint32_t (*DAQ331M_GetCurrentSampleRate)(uint32_t *base_class);
    uint32_t (*DAQ331M_ConfigDACMode)(uint32_t *base_class, uint32_t channel, uint32_t mode);
    uint32_t (*DAQ331M_ConfigDACDirectCurrentData)(uint32_t *base_class, uint32_t channel, double data);
    uint32_t (*DAQ331M_ConfigDACWaveData)(uint32_t *base_class, uint32_t channel, uint32_t frequency, double *data);
    uint32_t (*DAQ331M_StartDAC)(uint32_t *base_class, uint32_t channel);
    uint32_t (*DAQ331M_StopDAC)(uint32_t *base_class, uint32_t channel);
} daq331m_dll_t, *daq331m_dll_ptr;

struct daq331m
{
    daq331m_dll_t daq331m_dll_;
    uint32_t *daq331m_;
    void (*create_device)(daq331m_ptr daq331m);
    void (*delete_device)(daq331m_ptr daq331m);
    bool (*initialize_device)(daq331m_ptr daq331m);
    bool (*connected_device)(daq331m_ptr daq331m);
    bool (*use_serial_backend)(daq331m_ptr daq331m, const char *uart_name, uint32_t baud_rate);
    bool (*use_tcp_client_backend)(daq331m_ptr daq331m, const char *ip_address, int port);
    bool (*use_modbus_backend)(daq331m_ptr daq331m, const char *uart_name, int baud_rate, int address);
    bool (*configure_adc_parameters)(daq331m_ptr daq331m, uint32_t sample_rate, uint32_t voltage);
    bool (*configure_adc_channel)(daq331m_ptr daq331m, uint8_t channel_state);
    bool (*start_collection)(daq331m_ptr daq331m);
    bool (*stop_collection)(daq331m_ptr daq331m);
    bool (*try_read_adc_data)(daq331m_ptr daq331m, uint8_t channel, double *read_buffer, uint32_t read_size,
                              uint32_t timeout);
    uint32_t (*get_adc_enable_channel_size)(daq331m_ptr daq331m);
    uint32_t (*get_current_sample_rate)(daq331m_ptr daq331m);
    uint32_t (*get_adc_legal_channel_size)(daq331m_ptr daq331m);
    bool (*adc_data_is_ready)(daq331m_ptr daq331m, uint32_t data_num);
    bool (*config_dac_mode)(daq331m_ptr daq331m, uint32_t channel, uint32_t mode);
    bool (*config_dac_direct_current_data)(daq331m_ptr daq331m, uint32_t channel, double data);
    bool (*config_dac_wave_data)(daq331m_ptr daq331m, uint32_t channel, uint32_t frequency, double *data);
    bool (*start_dac)(daq331m_ptr daq331m, uint32_t channel);
    bool (*stop_dac)(daq331m_ptr daq331m, uint32_t channel);
};

bool daq331m_init(daq331m_ptr daq331m);
bool daq331m_deinit(daq331m_ptr daq331m);